package com.authine.cloudpivot.ext.applicationservice;

import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.applicationservice.base.ApplicationBaseService;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.dto.StockBillMaterialDto;
import com.authine.cloudpivot.ext.dto.StockBillVO;
import com.authine.cloudpivot.ext.utils.BoResultFormat;
import com.authine.cloudpivot.ext.utils.StringUtils;
import com.authine.common.json.JsonUtils;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.CollectionUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @ClassName VmiStockManageService
 * @Description: 寄售库存管理自定义服务
 * @Author cjj
 * @Date 2021/6/2
 * @Version V1.0
 **/
@Path("VmiStockManageService")
@Slf4j
public class VmiStockManageService extends ApplicationBaseService {
    private NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);

    /**
     * 寄售库存管理(库存-领用-/库存-退料-创建退料单/库存-盘点-创建盘点单)/寄售发货通知（待入库-生成入库存单-提交入库单）
     *
     * @param dto
     * @return
     */
    @Path("saveStockBill")
    @POST
    @Operation(summary = "寄售库存管理(库存-领用-创建领用单/库存-退料-创建退料单/库存-盘点-创建盘点单)/寄售发货通知（待入库-生成入库存-提交入库单）", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> saveStockBill(@Parameter StockBillVO dto) {
        return saveStockBillVO(dto);
    }

    /**
     * 寄售库存管理(领用单详情/退料单详情/盘点单详情)
     *
     * @param dto
     * @return
     */
    @Path("stockBillList")
    @POST
    @Operation(summary = "寄售库存管理(领用单详情/退料单详情/盘点单详情)", tags = CUSTOM_SERVICE, description = "id必填")
    public SingleResponse<BO> stockBillList(@Parameter StockBillVO dto) {
        log.info("------------------------寄售库存管理(领用单详情/退料单详情/盘点单详情) stockBillList Param：{}------------------------", JSONObject.toJSONString(dto));
        if (StringUtils.isBlank(dto.getId())) {
            return SingleResponse.buildFailure("-1", "库存相关单据ID必填");
        }
        String billTableName = getTableName(ModelConst.T_STOCK_BILL);
        String billMaterialTableName = getTableName(ModelConst.T_STOCK_BILL_MATERIAL);
        String billSql = "select * from " + billTableName + " where deleted ='0' and id ='" + dto.getId() + "' order by createdTime desc";
        //供应商订单集合
        List<Map<String, Object>> billList = jdbcTemplate.queryForList(billSql, new HashMap<>());
        if (CollectionUtils.isEmpty(billList)) {
            return SingleResponse.buildFailure("-1", "库存相关单据不存在");
        }
        String orderCustomerGoodsSql = "select * from " + billMaterialTableName + " where stock_bill_id ='" + dto.getId() + "' order by createdTime desc ";
        //客户订单商品集合
        List<Map<String, Object>> billMaterialList = jdbcTemplate.queryForList(orderCustomerGoodsSql, new HashMap<>());
        billList.get(0).put("billMaterialList", billMaterialList);
        //构建结果集
        BO bo = new BO();
        bo.setData(billList.get(0));
        bo.setSchemaCode(ModelConst.T_STOCK_BILL);
        return SingleResponse.of(bo);
    }

    /**
     * 盘亏、盘盈列表
     *
     * @param dto
     * @return
     */
    @Path("lossOrProfitList")
    @POST
    @Operation(summary = "寄售库存管理-盘亏、盘盈列表", tags = CUSTOM_SERVICE, description = "pageIndex、pageSize必填, type :5盘亏;6盘盈")
    public SingleResponse<BOList> lossOrProfitList(@Parameter StockBillMaterialDto dto) {
        log.info("------------------------寄售库存管理-盘亏、盘盈列表 lossOrProfitList Param：{}------------------------", JSONObject.toJSONString(dto));
        if (null == dto.getPageIndex() || null == dto.getPageSize()) {
            return SingleResponse.buildFailure("-1", "pageIndex、pageSize必填");
        }
        if (StringUtils.isBlank(dto.getType())) {
            return SingleResponse.buildFailure("-1", "类型必填");
        }
        String materialTableName = getTableName(ModelConst.T_STOCK_BILL_MATERIAL);
        String stockBillTableName = getTableName(ModelConst.T_STOCK_BILL);
        Map<String, Object> parameter = new HashMap<>();
        StringBuilder listSql = new StringBuilder();
        StringBuilder whereSql = new StringBuilder();
        StringBuilder countSql = new StringBuilder();
        listSql.append("select bm.* from " + materialTableName + " bm " +
                "LEFT JOIN " + stockBillTableName + " bi on bi.id = bm.stock_bill_id " +
                "where 1=1 and bi.stock_bill_status = 'WOKING' ");
        countSql.append("select count(*) from " + materialTableName + " bm " +
                "LEFT JOIN " + stockBillTableName + " bi on bi.id = bm.stock_bill_id " +
                "where 1=1 and bi.stock_bill_status = 'WOKING' ");
        //拼接参数
        //type
        if (StringUtils.isNotBlank(dto.getType())) {
            whereSql.append(" and bm.type = :type ");
            parameter.put("type", dto.getType());
        }
        //序号
        if (StringUtils.isNotBlank(dto.getId())) {
            List<String> ids = StringUtils.stringToListString(dto.getId(), ";");
            whereSql.append(" and bm.id in (:id) ");
            parameter.put("id", ids);
        }
        //客户名称
        if (StringUtils.isNotBlank(dto.getCustomerName())) {
            whereSql.append(" and bm.customer_name like :customer_name ");
            parameter.put("customer_name", "%" + dto.getCustomerName() + "%");
        }
        //供应商名称
        if (StringUtils.isNotBlank(dto.getVendorName())) {
            whereSql.append(" and bm.vendor_name like :vendor_name ");
            parameter.put("vendor_name", "%" + dto.getVendorName() + "%");
        }
        //品牌
        if (StringUtils.isNotBlank(dto.getBrand())) {
            whereSql.append(" and bm.brand like :brand ");
            parameter.put("brand", "%" + dto.getBrand() + "%");
        }
        //名称
        if (StringUtils.isNotBlank(dto.getName())) {
            whereSql.append(" and bm.name like :name ");
            parameter.put("name", "%" + dto.getName() + "%");
        }
        //型号
        if (StringUtils.isNotBlank(dto.getModel())) {
            whereSql.append(" and bm.model =:model ");
            parameter.put("model", dto.getModel());
        }
        //规格
        if (StringUtils.isNotBlank(dto.getSpec())) {
            whereSql.append(" and bm.spec =:spec ");
            parameter.put("spec", dto.getSpec());
        }
        //日期
        if (StringUtils.isNotBlank(dto.getStartTime()) && StringUtils.isNotBlank(dto.getEndTime())) {
            whereSql.append(" and bm.createdTime between :startTime and :endTime ");
            parameter.put("startTime", dto.getStartTime());
            parameter.put("endTime", dto.getEndTime());
        }
        countSql.append(whereSql);
        listSql.append(whereSql);
        listSql.append(" order by bm.createdTime desc");
        listSql.append(" limit " + dto.getPageIndex() * dto.getPageSize() + ", " + dto.getPageSize());
        log.info("------------------------寄售库存管理-盘亏、盘盈列表 lossOrProfitList listSql：{}------------------------parameter：{}", listSql, JsonUtils.toJson(parameter));
        log.info("------------------------寄售库存管理-盘亏、盘盈列表 lossOrProfitList whereSql：{}------------------------parameter：{}", whereSql, listSql, JsonUtils.toJson(parameter));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(listSql.toString(), parameter);
        Integer count = 0;
        try {
            count = jdbcTemplate.queryForObject(countSql.toString(), parameter, Integer.class);
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        //构建结果集
        BoResultFormat.resultFormat(resultList, ModelConst.T_STOCK_BILL_MATERIAL);
        BOList bOList = new BOList();
        bOList.setData(resultList);
        bOList.setTotal(count);
        bOList.setSchemaCode(ModelConst.T_STOCK_BILL_MATERIAL);
        return SingleResponse.of(bOList);
    }
}
